/******************************************************************************
描述：   LCD1602的C文件
硬件：	 89C52单片机
局部变量名：add; dat; x; i; *P; length
作者：卢建成
日期：2015/10/15
******************************************************************************/
#include "LCD1602.h"
#include <REGX51.H>
#include "delay.h"
#include  <intrins.h>/*包含含有_nop_()函数的头文件*/
	
sbit LCD_EN=P3^4;
sbit LCD_RS=P3^5;
sbit LCD_RW=P3^6;
/******************************************************************
函数名：LCD1602专用延时函数
调用：
参数：
返回值：
功能：延时
备注：需要根据不同的LCD型号修改参数,仿真和实际可能会不一样
******************************************************************/
void lcddelay(void)
{
	 Delay5Ms();
}


/******************************************************************
函数名：LCD1602写命令函数
调用：lcddelay()
参数：十六进制命令码
返回值：无
功能：向LCD1602写命令
备注：
******************************************************************/
void lcd_com(unsigned char x)
{
    LCD_RS=0;
    DB=x;
    lcddelay();
    LCD_EN=1;
    lcddelay();
    LCD_EN=0;
}




/******************************************************************
函数名：LCD1602写数据函数
调用： lcddelay()
参数： GGRAM地址
返回值：无
功能：让LCD1602显示字符
备注：
******************************************************************/
void lcd_data(unsigned char x)
{
    LCD_RS=1;
    DB=x; 
    lcddelay();
    LCD_EN=1;
    lcddelay();
    LCD_EN=0;
}





/******************************************************************
函数名：LCD1602初始化函数
调用：
参数：
返回值：
功能：设置LCD1602
备注：可以通过注释或解除注释改变设置
******************************************************************/
void LCD_init()
{
lcd_com(0x38);//显示模式设置
lcd_com(0x06);//光标模式设置
//lcd_com(0x0f);//显示开，光标显示，光标闪烁
lcd_com(0x0c);//显示开，光标不显示
lcd_com(0x01);//清屏
//lcd_com(0x02);//数据指针清零
//lcd_com(0x08);//显示关

}





/******************************************************************
函数名：LCD1602写入函数
调用：
参数：DDARM地址，字符的ASCI码
返回值：无
功能：在LCD1602指定位置写入一个字符
备注：
******************************************************************/
void LCD_writebyte(unsigned char add,unsigned char dat)//在指定位置写入一个字符
{
 lcd_com(0x80+add);//写入DDRAM地址
 lcddelay();
 lcd_data(dat);//写入 CGRAM地址，显示对应的字符 
}


/******************************************************************
函数名：LCD1602连续写入函数
调用：
参数：要显示的第一个字符的DDARM地址；字符数组首地址；字符长度。
返回值：无
功能：在LCD1602上显示一行字
备注：必须在使用前定义一个字符数组来装入要写入的字符；字符长度不大于16。
******************************************************************/
void LCD_write(unsigned char add,unsigned char *p,unsigned char length)//写入一行数据
{
   unsigned char  i;
   unsigned char dat;
   lcd_com(0x80+add);//写入DDRAM地址
   lcddelay();
   for(i=0;i<length;i++)
   {
   dat=*(p+i);
   lcd_data(dat);//写入 CGRAM地址，显示对应的字符
   }
}


/******************************************************************
函数:自定义字符函数
调用：
参数：字模存储位置，字模数据数组
返回值：
功能：自定义字符 配套字模数据数组(文件开头处），使用时删掉//
备注：第1到8个字符CGRAM地址：0,1,2,3,4,5,6,7  
******************************************************************
void write_ZIMO(unsigned char add,unsigned char *p)
{
	unsigned char  i;
	unsigned char dat;
	lcd_com(0x40+add);//写入CGRAM地址
  lcddelay();
  for(i=0;i<7;i++)
   {
   dat=*(p+i);
   lcd_data(dat);//写入字模数据
   }
 }

/***********************************************************/



//字模数组
unsigned char code Character[64]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x00,//字符年
								  0x0f,0x09,0x0f,0x09,0xf,0x09,0x11,0x00,  //字符月
								  0x0f,0x09,0x09,0x0f,0x09,0x09,0x0f,0x00, //字符日
								  0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00,//摄氏度
								  0,0,0,0,0,0,0,0,
								  0,0,0,0,0,0,0,0,
								  0,0,0,0,0,0,0,0,
								  0,0,0,0,0,0,0,0,								
								  };
/***********************函数定义区**************************************************/
 /******************************************************************
函数名：LCD1602测忙函数
调用：
参数：
返回值：
功能：设置LCD1602
备注：注意使用该函数时DB口不能有上拉电阻
******************************************************************/
unsigned char lcd_test(void)
{
    unsigned char x;
    DB=0xff;		//读信号前，置I/O口高电平
	LCD_RW=1;
	LCD_RS=0;
	LCD_EN=1;
	Delaynus(10);
	x=DB;	   //正式读数据
	LCD_EN=0;
	return x;
}

/*******************************************************************/






/******************************************************************
函数名：LCD1602初始化函数
调用：
参数：
返回值：
功能：设置LCD1602
备注：可以通过注释或解除注释改变设置
******************************************************************
void LCD_init(void)
{
lcd_com(0x38);
Delay5Ms();
lcd_com(0x38);
Delay5Ms();
lcd_com(0x38);
Delay5Ms();
lcd_com(0x38);//显示模式设置

lcd_com(0x08);//关显示
lcd_com(0x06);//光标模式设置

//lcd_com(0x0f);//显示开，光标显示，光标闪烁
lcd_com(0x0c);//显示开，光标不显示
lcd_com(0x01);//清屏
//lcd_com(0x02);//数据指针清零
//lcd_com(0x08);//显示关
//write_ZIMO(Character);
}





/******************************************************************
函数名：LCD1602写入函数
调用：
参数： 屏幕上的位置，字符的ASCI码
返回值：无
功能：在LCD1602指定位置写入一个字符
备注：
******************************************************************
void LCD_writebyte(unsigned char add,unsigned char dat)//在指定位置写入一个字符
{
 
 lcd_com(0x80+add);//写入DDRAM地址
 lcd_data(dat);//写入 CGRAM地址，显示对应的字符 
}


/******************************************************************
函数名：LCD1602连续写入函数
调用：
参数：要显示的第一个字符的DDARM地址；
      可选值：LineOne：第一行显示；
              LineSecond：第二行显示
      字符数组首地址；字符长度。
返回值：无
功能：在LCD1602上显示一行字
备注：必须在使用前定义一个字符数组来装入要写入的字符；字符长度不大于16。
******************************************************************
void LCD_write(unsigned char add,unsigned char *p,unsigned char length)//写入一行数据
{
   
   unsigned char  i;
   unsigned char dat;
   lcd_com(0x80+add);//写入DDRAM地址

     for(i=0;i<length;i++)
     {
      dat=*(p+i);
      lcd_data(dat);//写入 CGRAM地址，显示对应的字符

     }   
}


/******************************************************************
函数:设置自定义字符函数
调用：
参数：字模存储位置，字模数据数组
返回值：
功能：自定义字符 配套字模数据数组(文件开头处），使用时删掉//
备注：连续定义8个字符  字模数组大小64
******************************************************************/
void write_ZIMO(unsigned char *p)
{
	unsigned char  i;//字符的第几行
	unsigned char j;//第几个字符
	unsigned char dat;
  for(j=0;j<8;j++)
   {
	    for(i=0;i<8;i++)
      {
       dat=*(p+j*8+i);
       lcd_com(0x40+j*8+i);//写入CGRAM地址
       lcd_data(dat);//写入字模数据
	   }
    }
 }

/***********************************************************/